from flask import Flask, jsonify, request
from flask_cors import CORS
import sys
import os
import traceback
import json
import psycopg2
from psycopg2.extras import RealDictCursor

# 添加项目根目录到Python路径
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

# 导入utils模块中的函数
from backend.utils import (
    init_database, shuffle_new_deck, play_single_round, save_round_to_db,
    get_history, clear_history, get_timestamp, calculate_points,
    DB_CONFIG, DEFAULT_MAX_CARDS_LIMIT, DEFAULT_DECKS, LOW_CARDS_THRESHOLD,
    run_simulation, get_simulation_results, get_statistics
)

app = Flask(__name__)
# 确保JSON响应使用UTF-8字符集
app.config['JSON_AS_ASCII'] = False
# 允许跨域请求
CORS(app, resources={r"/api/*": {"origins": "*"}}, supports_credentials=True)

# 初始化数据库
print("Initializing database...")
if not init_database():
    print("Failed to initialize database. Exiting.")
    sys.exit(1)

# 全局游戏状态
class GameState:
    def __init__(self):
        self.deck = shuffle_new_deck(DEFAULT_DECKS)
        self.bet_choice = ''
        self.bet_amount = 0
        self.results_history = []
        self.current_round_result = None
        self.cards_dealt_count = 0
        self.max_cards_limit = DEFAULT_MAX_CARDS_LIMIT

    def reset_round(self):
        """重置一局游戏的数据"""
        self.bet_choice = ''
        self.current_round_result = None
        
        # 检查牌堆数量，如果少于6副牌则重新洗牌
        if len(self.deck) < LOW_CARDS_THRESHOLD:
            print("Not enough cards in the deck, shuffling...")
            self.deck = shuffle_new_deck(DEFAULT_DECKS)
            self.cards_dealt_count = 0
            print("Shuffling complete!")

game_state = GameState()

@app.route('/api/start-game', methods=['POST'])
def start_game():
    try:
        game_state.reset_round()
        return jsonify({"message": "Game started"})
    except Exception as e:
        print(f"Error in start_game: {str(e)}")
        print(traceback.format_exc())
        return jsonify({"error": str(e)}), 500

@app.route('/api/place-bet', methods=['POST'])
def place_bet():
    try:
        data = request.get_json()
        game_state.bet_choice = data.get('bet_choice')
        game_state.bet_amount = float(data.get('bet_amount'))
        print(f"Bet placed: {game_state.bet_choice}, amount: {game_state.bet_amount}")
        return jsonify({"message": "Bet placed"})
    except Exception as e:
        print(f"Error in place_bet: {str(e)}")
        print(traceback.format_exc())
        return jsonify({"error": str(e)}), 500

@app.route('/api/deal-cards', methods=['POST'])
def deal_cards():
    try:
        # 检查是否达到最大发牌数量限制
        if game_state.cards_dealt_count >= game_state.max_cards_limit:
            return jsonify({
                "error": f"已达到最大发牌数量 {game_state.max_cards_limit}，游戏结束",
                "cards_dealt_count": game_state.cards_dealt_count,
                "max_cards_limit": game_state.max_cards_limit,
                "game_ended": True
            }), 200

        # 使用utils中的play_single_round函数模拟一局游戏
        game_result = play_single_round(
            game_state.deck, 
            game_state.bet_choice, 
            game_state.bet_amount, 
            game_state.cards_dealt_count
        )
        
        if 'error' in game_result:
            return jsonify({"error": game_result['error']}), 400
        
        # 更新游戏状态
        game_state.deck = game_result['deck']
        game_state.cards_dealt_count = game_result['cards_dealt_count']
        game_state.current_round_result = game_result['result']
        
        # 将结果添加到历史中
        game_state.results_history.append(game_result['result'])
        
        # 如果有下注金额，保存记录到数据库
        if game_state.bet_amount > 0:
            save_round_to_db(game_result)
        
        # 提取响应所需数据
        player_hand = [card[0] for card in game_result['player_hand']]
        banker_hand = [card[0] for card in game_result['banker_hand']]
        
        cards_remaining = len(game_state.deck)
        remaining_deals = (game_state.max_cards_limit - game_state.cards_dealt_count) // 2
        
        return jsonify({
            "player_hand": player_hand,
            "banker_hand": banker_hand,
            "player_points": game_result['player_points'],
            "banker_points": game_result['banker_points'],
            "result": game_result['result'],
            "win": game_result['win'],
            "payout": game_result['payout'],
            "cards_dealt_count": game_state.cards_dealt_count,
            "max_cards_limit": game_state.max_cards_limit,
            "cards_remaining": cards_remaining,
            "remaining_deals": remaining_deals
        })
    except Exception as e:
        print(f"Error in deal_cards: {str(e)}")
        print(traceback.format_exc())
        return jsonify({"error": str(e)}), 500

@app.route('/api/history', methods=['GET'])
def get_game_history():
    try:
        print("Attempting to fetch history...")
        limit = request.args.get('limit', 10, type=int)
        history = get_history(limit)
        print(f"History fetched: {len(history)} records")
        return jsonify(history)
    except Exception as e:
        print(f"Error in get_history: {str(e)}")
        print(traceback.format_exc())
        return jsonify({"error": str(e)}), 500

@app.route('/api/clear-history', methods=['POST'])
def clear_game_history():
    try:
        print("Clearing all history...")
        success = clear_history()
        
        if success:
            # 重置游戏状态
            game_state.reset_round()
            game_state.results_history = []
            
            print("All history cleared successfully")
            return jsonify({"message": "All history cleared successfully"})
        else:
            return jsonify({"error": "Failed to clear history"}), 500
    except Exception as e:
        print(f"Error in clear_history: {str(e)}")
        print(traceback.format_exc())
        return jsonify({"error": str(e)}), 500

@app.route('/api/cards-status', methods=['GET'])
def get_cards_status():
    try:
        return jsonify({
            "cards_dealt_count": game_state.cards_dealt_count,
            "max_cards_limit": game_state.max_cards_limit,
            "cards_remaining": len(game_state.deck),
            "remaining_deals": (game_state.max_cards_limit - game_state.cards_dealt_count) // 2
        })
    except Exception as e:
        print(f"Error in get_cards_status: {str(e)}")
        print(traceback.format_exc())
        return jsonify({"error": str(e)}), 500

# 新增API端点，用于策略模拟测试
@app.route('/api/simulations/run', methods=['POST'])
def run_strategy_simulation():
    try:
        data = request.get_json()
        strategy_name = data.get('strategy_name', '三反四看五跟策略')
        deck_seed = data.get('deck_seed')
        max_rounds = data.get('max_rounds', 1000)
        parameters = data.get('parameters', {})
        
        # 输出strategy_name字符编码调试信息
        print(f"策略名称: {strategy_name}, 类型: {type(strategy_name)}, 编码样例: {strategy_name.encode('utf-8')}")
        
        # 运行模拟
        print(f"Starting simulation: {strategy_name}, rounds: {max_rounds}")
        simulation_result = run_simulation(strategy_name, deck_seed, max_rounds, parameters)
        
        if not simulation_result:
            return jsonify({"error": "Failed to run simulation"}), 500
            
        print(f"Simulation completed: ID={simulation_result['simulation_id']}")
        return jsonify(simulation_result)
    except Exception as e:
        print(f"Error in run_strategy_simulation: {str(e)}")
        print(traceback.format_exc())
        return jsonify({"error": str(e)}), 500

@app.route('/api/simulation/<int:simulation_id>', methods=['GET'])
def get_simulation_detail(simulation_id):
    try:
        result = get_simulation_results(simulation_id)
        if not result:
            return jsonify({"error": "Simulation not found"}), 404
        return jsonify(result)
    except Exception as e:
        print(f"Error in get_simulation_detail: {str(e)}")
        print(traceback.format_exc())
        return jsonify({"error": str(e)}), 500

@app.route('/api/simulations', methods=['GET'])
def list_simulations():
    try:
        # 获取所有模拟记录
        conn = psycopg2.connect(**DB_CONFIG)
        cursor = conn.cursor(cursor_factory=RealDictCursor)
        
        cursor.execute('''
            SELECT id, timestamp, strategy_name, total_rounds, win_rounds, 
                   lose_rounds, net_profit, deck_seed 
            FROM simulations 
            ORDER BY id DESC
        ''')
        
        simulations = cursor.fetchall()
        cursor.close()
        conn.close()
        
        return jsonify(simulations)
    except Exception as e:
        print(f"Error in list_simulations: {str(e)}")
        print(traceback.format_exc())
        return jsonify({"error": str(e)}), 500

@app.route('/api/clear-simulations', methods=['POST'])
def clear_all_simulations():
    try:
        # 清空所有模拟记录及相关的轮次记录
        conn = psycopg2.connect(**DB_CONFIG)
        cursor = conn.cursor()
        
        # 先删除所有模拟轮次记录（因为有外键约束）
        cursor.execute('DELETE FROM simulation_rounds')
        # 再删除所有模拟记录
        cursor.execute('DELETE FROM simulations')
        # 最后删除相关的牌组记录
        cursor.execute('DELETE FROM decks WHERE simulation_id IS NOT NULL')
        
        conn.commit()
        cursor.close()
        conn.close()
        
        return jsonify({"message": "所有模拟记录已清空"}), 200
    except Exception as e:
        print(f"Error in clear_all_simulations: {str(e)}")
        print(traceback.format_exc())
        return jsonify({"error": str(e)}), 500

@app.route('/api/clear-simulation/<int:simulation_id>', methods=['POST'])
def clear_simulation(simulation_id):
    try:
        from backend.utils import clear_simulation as utils_clear_simulation
        success = utils_clear_simulation(simulation_id)
        
        if success:
            return jsonify({"message": f"Simulation {simulation_id} cleared successfully"})
        else:
            return jsonify({"error": f"Failed to clear simulation {simulation_id}"}), 500
    except Exception as e:
        print(f"Error in clear_simulation: {str(e)}")
        print(traceback.format_exc())
        return jsonify({"error": str(e)}), 500

@app.route('/api/statistics', methods=['GET'])
def get_game_statistics():
    """获取游戏统计数据"""
    try:
        stats = get_statistics()
        if stats:
            response = jsonify(stats)
            # 添加CORS头部
            response.headers.add('Access-Control-Allow-Origin', '*')
            return response
        else:
            return jsonify({"error": "Failed to fetch statistics"}), 500
    except Exception as e:
        print(f"Error in get_game_statistics: {str(e)}")
        print(traceback.format_exc())
        return jsonify({"error": str(e)}), 500

if __name__ == '__main__':
    app.run(debug=True, port=5003, host='0.0.0.0') 